home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / write.c < prev   
C/C++ Source or Header  |  1990-07-23  |  6KB  |  261 lines

  1. /* write - write to a logged in user    Authors: N. Andrew and F. van Kempen */
  2.  
  3. /*
  4.  * Usage:    write [-c] [-v] user [tty]
  5.  *              -c Read & write one character at a time (cbreak mode)
  6.  *            -v Verbose
  7.  *
  8.  * Version:    1.5    01/09/90
  9.  *
  10.  * NOTES:    Write requires 1.4a (or higher) libraries,
  11.  *        for getopt(), strchr().
  12.  *
  13.  * Authors:    Nick Andrew  (nick@nswitgould.oz)  - Public Domain
  14.  *        Fred van Kempen (minixug!waltje@kyber.uucp)
  15.  */
  16.  
  17. #include <sys/types.h>
  18. #include <fcntl.h>
  19. #include <pwd.h>
  20. #include <sgtty.h>
  21. #include <signal.h>
  22. #include <string.h>
  23. #include <time.h>
  24. #include <utmp.h>
  25. #include <unistd.h>
  26. #include <stdio.h>
  27.  
  28.  
  29. static char *Version = "@(#) WRITE 1.5 (01/09/90)";
  30.  
  31. int otty;            /* file desc of callee's terminal */
  32. short int cbreak = 0;        /* are we in CBREAK (-c) mode? */
  33. short int verbose = 0;        /* are we in VERBOSE (-v) mode? */
  34. short int writing = 0;        /* is there a connection? */
  35. char *user = NULL;        /* callee's user name */
  36. char *tty = NULL;        /* callee's terminal if given */
  37. char *ourtty = NULL;        /* our terminal name */
  38. struct sgttyb ttyold, ttynew;    /* our tty controlling structs */
  39.  
  40. extern int getopt(), optind;    /* from getopt(3) */
  41. void intr();
  42.  
  43. char *finduser()
  44. {
  45. /* Search the UTMP database for the user we want. */
  46.  
  47.   static char utmptty[16];
  48.   struct utmp utmp;
  49.   struct passwd *userptr;
  50.   char ourname[9];
  51.   int utmpfd;
  52.  
  53.   ourtty = ttyname(0);
  54.   if (ourtty == NULL) ourtty = "/dev/console";
  55.  
  56.   if (user == NULL) exit(-1);
  57.   if ((userptr = getpwnam(user)) == NULL) {
  58.     fprintf(stderr, "No such user: %s\n", user);
  59.     return(NULL);
  60.   }
  61.   if (verbose) fprintf(stderr, "Trying to write to %s\n",
  62.         userptr->pw_gecos);
  63.  
  64.   if ((utmpfd = open(UTMP, O_RDONLY)) < 0) {
  65.     fprintf(stderr, "Cannot open utmp file\n");
  66.     return((char *) NULL);
  67.   }
  68.   utmptty[0] = '\0';
  69.  
  70.   /* We want to find if 'user' is logged on, and return in utmptty[]
  71.    * 'user' `s terminal, and if 'user' is logged onto the tty the
  72.    * caller specified, return that tty name. */
  73.   while (read(utmpfd, (char *) &utmp, sizeof(utmp)) == sizeof(utmp)) {
  74.     /* is this the user we are looking for? */
  75.     if (strcmp(utmp.ut_name, user)) continue;
  76.  
  77.     /* is he on the terminal we want to write to? */
  78.     if (tty == NULL || strcmp(utmptty, tty)) {
  79.         strcpy(utmptty, utmp.ut_line);
  80.         break;
  81.     }
  82.   }
  83.  
  84.   if (utmptty[0] == '\0') {
  85.     fprintf(stderr, "%s is not logged on\n", user);
  86.     return( (char *) NULL);
  87.   }
  88.   if (tty != NULL && strcmp(utmptty, tty)) {
  89.     fprintf(stderr, "%s is logged onto %s, not %s\n", user, utmptty, tty);
  90.     return( (char *) NULL);
  91.   }
  92.   close(utmpfd);
  93.  
  94.   if (verbose) fprintf(stderr, "Writing to %s on %s\n", user, utmptty);
  95.   return(utmptty);
  96. }
  97.  
  98.  
  99. void settty(utty)
  100. char *utty;            /* name of terminal found in utmp */
  101. {
  102. /* Open other person's terminal and setup our own terminal. */
  103.  
  104.   char buff[48];
  105.  
  106.   sprintf(buff, "/dev/%s", utty);
  107.   if ((otty = open(buff, O_WRONLY)) < 0) {
  108.     fprintf(stderr, "Cannot open %s to write to %s\n", utty, user);
  109.     fprintf(stderr, "It may have write permission turned off\n");
  110.     exit(-1);
  111.   }
  112.   ioctl(0, TIOCGETP, &ttyold);
  113.   ioctl(0, TIOCGETP, &ttynew);
  114.   ttynew.sg_flags |= CBREAK;
  115.   signal(SIGINT, intr);
  116.   if (cbreak) ioctl(0, TIOCSETP, &ttynew);
  117. }
  118.  
  119.  
  120. void sayhello()
  121. {
  122.   struct passwd *pw;
  123.   char buff[128];
  124.   long now;
  125.   char *sp;
  126.  
  127.   time(&now);
  128.  
  129.   pw = getpwuid(getuid());
  130.   if (pw == NULL) {
  131.     fprintf(stderr, "unknown user\n");
  132.     exit(-1);
  133.   }
  134.   if ((sp = strrchr(ourtty, '/')) != NULL)
  135.     ++sp;
  136.   else
  137.     sp = ourtty;
  138.  
  139.   sprintf(buff, "\nMessage from %s (%s) %-24.24s...\n",
  140.     pw->pw_name, sp, ctime(&now));
  141.  
  142.   write(otty, buff, strlen(buff));
  143.   printf("\007\007");
  144.   fflush(stdout);
  145. }
  146.  
  147.  
  148. void escape(cmd)
  149. char *cmd;
  150. {
  151. /* Shell escape. */
  152.  
  153.   register char *x;
  154.  
  155.   write(1, "!\n", 2);
  156.   for (x = cmd; *x; ++x)
  157.     if (*x == '\n') *x = '\0';
  158.  
  159.   system(cmd);
  160.   write(1, "!\n", 2);
  161. }
  162.  
  163.  
  164. void writetty()
  165. {
  166. /* The write loop. */
  167.  
  168.   char line[80];
  169.   int n, cb_esc;
  170.  
  171.   writing = 1;
  172.   cb_esc = 0;
  173.  
  174.   while ((n = read(0, line, 79)) > 0) {
  175.     if (line[0] == '\004') break;    /* EOT */
  176.  
  177.     if (cbreak && line[0] == '\n') cb_esc = 1;
  178.  
  179.     if (line[0] == '!') {
  180.         if (cbreak && cb_esc) {
  181.             cb_esc = 0;
  182.             ioctl(0, TIOCSETP, &ttyold);
  183.             read(0, line, 79);
  184.             escape(line);
  185.             ioctl(0, TIOCSETP, &ttynew);
  186.         } else if (cbreak)
  187.             write(otty, line, n);
  188.         else
  189.             escape(&line[1]);
  190.         continue;
  191.     }
  192.     write(otty, line, n);
  193.   }
  194.   write(1, "\nEOT\n", 5);
  195.   write(otty, "\nEOT\n", 5);
  196. }
  197.  
  198.  
  199. void usage()
  200. {
  201.   fprintf(stderr, "usage: write [-c] [-v] user [tty]\n");
  202.   fprintf(stderr, "\t-c : cbreak mode\n\t-v : verbose\n");
  203.   exit(-1);
  204. }
  205.  
  206.  
  207. main(argc, argv)
  208. int argc;
  209. char *argv[];
  210. {
  211.   register int c;
  212.   char *sp;
  213.  
  214.   setbuf(stdout, (char *) NULL);
  215.  
  216.   /* Parse options. */
  217.   while ((c = getopt(argc, argv, "cv")) != EOF) switch (c) {
  218.             case 'c':    cbreak = 1;    break;
  219.             case 'v':    verbose = 1;    break;
  220.         default:
  221.         usage();
  222.     }
  223.  
  224.   /* Parse user and tty arguments */
  225.   if (optind < argc) {
  226.     user = argv[optind++];
  227.  
  228.     /* WTMP usernames are 1-8 chars */
  229.     if (strlen(user) > 8) *(user + 8) = '\0';
  230.  
  231.     if (optind < argc) {
  232.         tty = argv[optind++];
  233.         if (optind < argc) usage();
  234.     }
  235.   } else
  236.     usage();
  237.  
  238.   sp = finduser();        /* find which tty to write onto */
  239.   if (sp != NULL) {        /* did we find one? */
  240.     settty(sp);        /* setup our terminal */
  241.     sayhello();        /* print the initial message */
  242.     writetty();        /* the write loop */
  243.     ioctl(0, TIOCSETP, &ttyold);
  244.     exit(0);
  245.   }
  246.   exit(-1);
  247. }
  248.  
  249. void intr()
  250. {
  251. /* The interrupt key has been hit. exit cleanly. */
  252.  
  253.   signal(SIGINT, SIG_IGN);
  254.   fprintf(stderr, "\nInterrupt. Exiting write\n");
  255.   ioctl(0, TIOCSETP, &ttyold);
  256.   if (writing) write(otty, "\nEOT\n", 5);
  257.   exit(0);
  258. }
  259.  
  260.  
  261.